package org.chen.aao.ai.service.translate;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.cloud.translate.v3.LocationName;
import com.google.cloud.translate.v3.TranslateTextRequest;
import com.google.cloud.translate.v3.TranslateTextResponse;
import com.google.cloud.translate.v3.TranslationServiceClient;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.chen.aao.ai.feign.SubsServiceClient;
import org.chen.aao.ai.mapper.TranslateHistoryMapper;
import org.chen.aao.ai.service.ITranslateService;
import org.chen.aao.common.ai.dto.TranslateHistoryResponse;
import org.chen.aao.common.ai.dto.TranslateRequest;
import org.chen.aao.common.ai.dto.TranslateResponse;
import org.chen.aao.common.ai.entity.TranslateHistory;
import org.chen.aao.common.exception.AIServiceException;
import org.chen.aao.common.exception.BusinessException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class TranslateServiceImpl implements ITranslateService {

    private final TranslateHistoryMapper translateHistoryMapper;
    private final RedisTemplate<String, Object> redisTemplate;
    private final TranslationServiceClient translationClient;
    private final SubsServiceClient subsServiceClient;

    @Value("${ai.google.project-id}")
    private String googleProjectId;

    @Override
    @Cacheable(value = "translations", key = "#request.text + #request.sourceLang + #request.targetLang")
    // 翻译功能
    public TranslateResponse translate(TranslateRequest request, Long userId) {
        // 检查配额
        checkQuota(userId, "translation", getMaxDailyTranslations(userId));

        try {
            LocationName parent = LocationName.of(googleProjectId, "global");

            TranslateTextRequest translateRequest = TranslateTextRequest.newBuilder()
                    .setParent(parent.toString())
                    .setMimeType("text/plain")
                    .setSourceLanguageCode(request.getSourceLang())
                    .setTargetLanguageCode(request.getTargetLang())
                    .addContents(request.getText())
                    .build();

            TranslateTextResponse response = translationClient.translateText(translateRequest);
            String translatedText = response.getTranslationsList().get(0).getTranslatedText();

            // 更新使用统计
            updateUsageStats(userId, "translation", 1);

            // 保存翻译历史（可选）
            saveTranslationHistory(userId, request, translatedText);

            return TranslateResponse.builder()
                    .translatedText(translatedText)
                    .detectedLanguage(response.getTranslationsList().get(0).getDetectedLanguageCode())
                    .build();

        } catch (Exception e) {
            log.error("Translation error: {}", e.getMessage());
            throw new AIServiceException("翻译服务暂时不可用");
        }
    }

    @Override
    public TranslateHistoryResponse getTranslateHistory(Long userId, int page, int size) {
        Page<TranslateHistory> pageRequest = new Page<>(page, size);
        QueryWrapper<TranslateHistory> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);

        queryWrapper.orderByDesc("created_at");

        Page<TranslateHistory> historyPage = translateHistoryMapper.selectPage(pageRequest, queryWrapper);

        List<TranslateHistoryResponse.Translation> translations = historyPage.getRecords().stream()
                .map(history -> TranslateHistoryResponse.Translation.builder()
                        .id(String.valueOf(history.getId()))
                        .sourceText(history.getSourceText())
                        .translatedText(history.getTranslatedText())
                        .sourceLang(history.getSourceLang())
                        .targetLang(history.getTargetLang())
                        .createdAt(history.getCreatedAt())
                        .build())
                .collect(Collectors.toList());

        return TranslateHistoryResponse.builder()
                .translations(translations)
                .total((int) historyPage.getTotal())
                .hasMore(historyPage.hasNext())
                .build();
    }

    // 检查配额
    private void checkQuota(Long userId, String type, int maxLimit) {
        String cacheKey = String.format("%s:user:%d:daily", type, userId);
        Integer usage = (Integer) redisTemplate.opsForValue().get(cacheKey);

        if (usage != null && usage >= maxLimit) {
            throw new BusinessException(String.format("每日%s次数已达上限",
                    type.equals("chat") ? "聊天" :
                            type.equals("translation") ? "翻译" : "语音转文字"));
        }
    }

    // 更新使用统计
    private void updateUsageStats(Long userId, String type, int count) {
        LocalDate today = LocalDate.now();

        // 更新每日统计
        String dailyKey = String.format("usage:daily:%d:%s", userId, today);
        redisTemplate.opsForHash().increment(dailyKey, type, count);
        redisTemplate.expire(dailyKey, 2, TimeUnit.DAYS);

        // 更新每月统计
        String monthlyKey = String.format("usage:monthly:%d:%s", userId, today.withDayOfMonth(1));
        redisTemplate.opsForHash().increment(monthlyKey, type, count);
        redisTemplate.expire(monthlyKey, 35, TimeUnit.DAYS);

        // 更新限流计数
        String rateLimitKey = String.format("%s:user:%d:daily", type, userId);
        redisTemplate.opsForValue().increment(rateLimitKey);
        redisTemplate.expire(rateLimitKey, 1, TimeUnit.DAYS);
    }

    private int getMaxDailyTranslations(Long userId) {
        return getMaxDailyTranslationsById(getSubscriptionLevel(userId));
    }

    private int getMaxDailyTranslationsById(String subscriptionLevel) {
        return switch (subscriptionLevel) {
            case "PREMIUM" -> 2000;
            case "BASIC" -> 200;
            default -> 20;
        };
    }

    // 获取订阅等级
    private String getSubscriptionLevel(Long userId) {
        String cacheKey = "user:subscription:" + userId;
        String level = (String) redisTemplate.opsForValue().get(cacheKey);
        if (level == null) {
            level = subsServiceClient.getSubscriptionStatusById(userId).getData().getPlan();
            redisTemplate.opsForValue().set(cacheKey, level, 1, TimeUnit.HOURS);
        }
        return level;
    }


    // 保存翻译历史
    public void saveTranslationHistory(Long userId, TranslateRequest request, String translatedText) {
        // 保存聊天记录
        TranslateHistory history = new TranslateHistory();
        history.setUserId(userId);
        history.setSourceText(request.getText());
        history.setSourceLang(request.getSourceLang());
        history.setTranslatedText(translatedText);
        history.setTargetLang(request.getTargetLang());
        translateHistoryMapper.insert(history);
        log.info("Translation saved for user {}: {} -> {}", userId, request.getSourceLang(), request.getTargetLang());
    }
}
